package api

import (
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"blockchain-api/internal/models"
	"blockchain-api/pkg/logger"
)

// getBlockchainInfo 获取区块链信息
// @Summary 获取区块链信息
// @Description 获取区块链的基本信息，包括高度、难度等
// @Tags blockchain
// @Produce json
// @Success 200 {object} models.BlockchainInfo
// @Failure 500 {object} map[string]string
// @Router /blockchain/info [get]
func (s *Server) getBlockchainInfo(c *gin.Context) {
	// 获取区块链信息
	info, err := s.services.Blockchain.GetBlockchainInfo()
	if err != nil {
		logger.Error("Failed to get blockchain info:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get blockchain info"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    info,
	})
}

// validateBlockchain 验证区块链
// @Summary 验证区块链
// @Description 验证整个区块链的完整性
// @Tags blockchain
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Failure 500 {object} map[string]string
// @Router /blockchain/validate [get]
func (s *Server) validateBlockchain(c *gin.Context) {
	// 验证区块链
	isValid, err := s.services.Blockchain.ValidateBlockchain()
	if err != nil {
		logger.Error("Failed to validate blockchain:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to validate blockchain"})
		return
	}

	status := "invalid"
	if isValid {
		status = "valid"
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data": gin.H{
			"status": status,
			"valid":  isValid,
		},
	})
}

// getBlocks 获取区块列表
// @Summary 获取区块列表
// @Description 获取区块链中的区块列表
// @Tags blockchain
// @Produce json
// @Param limit query int false "限制返回数量"
// @Param offset query int false "偏移量"
// @Success 200 {object} map[string]interface{}
// @Failure 500 {object} map[string]string
// @Router /blockchain/blocks [get]
func (s *Server) getBlocks(c *gin.Context) {
	// 解析查询参数
	limitStr := c.DefaultQuery("limit", "10")
	offsetStr := c.DefaultQuery("offset", "0")

	limit, err := strconv.Atoi(limitStr)
	if err != nil || limit < 0 {
		limit = 10
	}

	offset, err := strconv.Atoi(offsetStr)
	if err != nil || offset < 0 {
		offset = 0
	}

	// 获取区块列表
	blocks, total, err := s.services.Blockchain.GetBlocks(limit, offset)
	if err != nil {
		logger.Error("Failed to get blocks:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get blocks"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    blocks,
		"total":   total,
		"limit":   limit,
		"offset":  offset,
	})
}

// getBlock 获取单个区块
// @Summary 获取单个区块
// @Description 根据区块索引获取区块详细信息
// @Tags blockchain
// @Produce json
// @Param index path int true "区块索引"
// @Success 200 {object} models.BlockResponse
// @Failure 400 {object} map[string]string
// @Failure 404 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /blockchain/blocks/{index} [get]
func (s *Server) getBlock(c *gin.Context) {
	indexStr := c.Param("index")
	index, err := strconv.ParseInt(indexStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid block index"})
		return
	}

	// 获取区块
	block, err := s.services.Blockchain.GetBlock(index)
	if err != nil {
		logger.Error("Failed to get block:", err)
		c.JSON(http.StatusNotFound, gin.H{"error": "Block not found"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"data":    block,
	})
}

// mineBlock 挖矿
// @Summary 挖矿
// @Description 开始挖矿过程，创建新区块
// @Tags blockchain
// @Accept json
// @Produce json
// @Param request body models.MineBlockRequest true "挖矿请求"
// @Success 200 {object} models.MineBlockResponse
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /blockchain/mine [post]
func (s *Server) mineBlock(c *gin.Context) {
	var req models.MineBlockRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		logger.Error("Invalid request body:", err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request body: " + err.Error()})
		return
	}

	// 验证矿工地址
	if !s.services.Wallet.ValidateAddress(req.MinerAddress) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid miner address"})
		return
	}

	// 开始挖矿
	response, err := s.services.Blockchain.MineBlock(req.MinerAddress)
	if err != nil {
		logger.Error("Failed to mine block:", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to mine block: " + err.Error()})
		return
	}

	logger.Info("Block mined successfully:", response.BlockHash)
	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "Block mined successfully",
		"data":    response,
	})
}
